<template>
  <div class="monaco-editor-box">
    <div class="function-group">
      {{fullName}}{{obj.private.content === obj.private.initContent ? '' : '*'}}
      <dec-button :text="'编译'" @trigger="clickCompile" :time="2"></dec-button>
      <dec-button :text="'保存'" @trigger="saveCurrentFile(obj)" :time="3"></dec-button>
    </div>
    <div class="monaco-editor-node" ref="editorNode"></div>
    <terminal-info></terminal-info>
  </div>
</template>
<script>
import _ from 'lodash'
import modelManager from './manager/modelManager'
import terminalInfo from './TerminalInfo'
import decButton from './DecButton'
// 如果使用路由可以通过一个变量保存当前dom，达到复用状态
export default {
  name: 'MonacoEditor',
  components: {
    terminalInfo,
    decButton
  },
  data () {
    return {
      editor: null,
      handleWindowResize: null,
      timeLeft: 0,
      timer: null
    }
  },
  computed: {
    fullName () {
      const nameList = []
      let node = this.obj
      while (node.parent) {
        nameList.unshift(node.name)
        node = node.parent
      }
      return nameList.join('/')
    }
  },
  props: {
    file: {
      type: String
    },
    options: {
      type: Object
    },
    value: {
      type: String,
      default: ''
    },
    obj: {
      type: Object
    },
    theme: {
      type: String
    },
    language: {
      type: String
    }
  },
  mounted () {
    this.handleWindowResize = _.debounce(() => {
      this.editor && this.editor.layout()
    }, 100)
    window.loadMonacoFile.then(res => {
      this.initMonaco()
    })
    window.addEventListener('resize', this.handleWindowResize)
  },
  beforeDestroy () {
    this.editor && this.editor.dispose()
    this.editor = null
    window.removeEventListener('resize', this.handleWindowResize)
  },
  watch: {
    file (n) {
      this.editor &&
      this.editor.setModel(modelManager.getModel(n, this.value, false, this.language)) &&
      this.editor.updateOptions({
        ...this.options,
        theme: this.theme,
        language: this.language
      })
    },
    options: {
      deep: true,
      handler (n) {
        this.editor && this.editor.updateOptions(n)
      }
    },
    value (n, o) {
      this.editor && n !== this.editor.getValue() && this.editor.setValue(n)
    }
  },
  methods: {
    initMonaco () {
      let monaco = window.monaco
      this.editor = monaco.editor.create(this.$refs.editorNode, {
        model: modelManager.getModel(this.file, this.value, false, this.language),
        ...this.options,
        theme: this.theme,
        language: this.language
      })
      this.$emit('editorDidMount', this.editor)
      this.afterDidMountHook()
    },
    afterDidMountHook () {
      this.handleWindowResize()
      this.editor.onContextMenu(event => this.$emit('contextMenu', event))
      this.editor.onDidChangeModel(event => this.$emit('model', event))
      this.editor.onDidChangeModelContent(event => {
        const value = this.editor.getValue()
        if (this.value !== value) {
          this.$emit('change', {
            value,
            file: this.file
          }, event)
        }
      })
    },
    saveCurrentFile (obj) {
      this.$emit('click-save', {
        file: this.file
      })
    },
    clickCompile () {
      this.$emit('click-cmpl')
    }
  }
}
</script>
<style scoped>
  .function-group {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    height: 40px;
    line-height: 40px;
    z-index: 100;
    padding: 0 20px;
    background: #222;
    color: #FFF;
  }
  .monaco-editor-box {
    position: absolute;
    left: 300px;
    right: 0;
    bottom: 0;
    top: 0;
    background: #1E1E1E;
  }
  .monaco-editor-node {
    position: absolute;
    left: 0;
    right: 0;
    top: 50px;
    bottom: 100px;
  }
  .save-btn {
    user-select: none;
    float: right;
    height: 20px;
    line-height: 20px;
    margin-top: 8px;
    padding: 0 15px;
    font-size: 12px;
    border-radius: 10px;
    border: 1px solid #FFF;
    background: #FFF;
    color: #000;
    cursor: pointer;
  }
  .save-btn:hover {
    background: #569cd6;
    border: 1px solid #569cd6;
    color: #FFF;
  }
  .compile-btn {
    margin-right: 10px;
  }
  .disabled-btn {
    background: #DDD;
    border: 1px solid #DDD;
    color: #666;
  }
</style>
